#include <stdio.h>
#include <stdlib.h>

void set(int [],int,int,int);
int get(int [],int,int);
int read(int [],int);

int main()
{
	int n,t,i,j,*a;
	scanf("%d",&n);//输入
	
	a=malloc(sizeof(int)*n*(n-1)/2);//创建数组
	
	for(i=1;i<=n;i++){
		for(j=1;j<i;j++){
		scanf("%d",&t);//输入
		set(a,j,i,t);//导入数组
		}
		for(j=i;j<=n;j++)	scanf("%d",&t);	//输入
	}//ok

	for(i=1;i<=6;i++)	{	
		if(!read(a,n)) {	
			printf("YES\n");
			if(a==	NULL)	free(a);
			return 0;
		}
	}
	for(t=0;t<n*(n-1)/2;t++){
		i=row(a,t);	j=line(a,t);
		if(!get(a,j,i)){ 
			printf("NO\n");	
			if(a==	NULL)	free(a);
			return 0;
		}
	}
	printf("YES\n");
	if(a==	NULL)	free(a);
	return 0;
}

int get(int a[],int j,int i){
	int sum=0,k=1,t;
	if(i==j)	return 0;
	if(i<j) {t=i;i=j;j=t;}
	for(k=1;k<=i;k++)	sum+=k;
	sum+=j;
	return a[sum-1];
}//用一维数组表示二维数组的读操作 OK

void set(int a[],int j,int i,int n){
	int sum=0,k=1,t;
	if(i<j) {t=i;i=j;j=t;}
	for(k=1;k<=i;k++)	sum+=k;
	sum+=j;
	a[sum-1]=n;
}//用一维数组表示二维数组的写操作 OK

int line(int a[],int k){
	int i=1;
	k++;
	while(k>i){
		k-=i;
		i++;		
	}
	return k;
}

int row(int a[],int k){
	int i=1;	k++;
	while(k>i){
		k-=i;
		i++;}
	i++;
	return i;
}

int read(int a[],int n){
	int i,j,k,t,b=0;;
	for(t=0;t<n*(n-1)/2;t++){
		i=row(a,t);	j=line(a,t);
		if(!get(a,i,j)){ 
			b++;
			for(k=1;k<=n;k++)
				if(get(a,k,i)&&get(a,k,j)&&(get(a,k,i)+get(a,k,i)<=6)){ 
					set(a,i,j,get(a,k,i)+get(a,k,j));
					break;
			}
		}	
	}
return b;
}//对数组的一次遍历操作,如果没有发现相互不认识的，则返回0.
